<template>
  <div
    class="virtually-list"
    :style="{ height: `${itemHeight * count}px` }"
    @scroll="scrollHandler"
  >
    <div class="virtually-list-dom" :style="{ top: `${start * itemHeight}px` }">
      <div
        v-for="(item, index) in list"
        :key="key ? item[key] : `dom-${index}`"
        :data-id="item[key]"
        class="vld-item"
      >
        <slot :item="item">
          <template v-if="item.render">
            <RenderBox :renderFun="item.render" :data="item" />
          </template>
          <template v-else-if="item.formmat">{{ item.formmat(item) }}</template>
          <template v-else>{{ item }}</template>
        </slot>
      </div>
    </div>
    <div
      class="virtually-list-bg"
      :style="{ height: `${data.length * itemHeight}px` }"
    ></div>
  </div>
</template>
<script setup lang="ts">
import { computed, onMounted, ref } from 'vue'
import RenderBox from './RenderBox/index.vue'
const props = defineProps({
  // 数据列表
  data: {
    type: Array<any>,
    default: () => [],
  },
  //   用于循环中的 key 尽量使用唯一标识符
  key: { type: String, default: 'id' },
  //   每一个item的高度
  height: { type: [String, Number], default: 20 },
  //   显示的数量
  count: { type: Number, default: 8 },
})
const start = ref(0)
const comHeight = computed(() => {
  return Number(props.height)
})
const end = computed(() => {
  return start.value + props.count
})
const list = computed(() => {
  console.log('list computed', start.value, 'end: ', end.value)

  return props.data.slice(start.value, end.value)
})
const itemHeight = ref<number>(Number(props.height))
onMounted(() => {
  const dom = document.querySelector('.vld-item')
  itemHeight.value = Math.max(comHeight.value, dom?.clientHeight || 0)
})
const scrollHandler = (event: MouseEvent) => {
  start.value = Math.floor(((event.target as HTMLDivElement)?.scrollTop || 0) / itemHeight.value)
}
</script>
<style lang="scss" scoped>
.virtually-list {
  position: relative;
  overflow-y: auto;
  .virtually-list-bg {
    height: 100%;
  }
  .virtually-list-dom {
    height: 100%;
    position: absolute;
    top: 0;
    left: 0;
  }
}
</style>
